/*
*    At least 2 modules
*    At least 3 interfaces
*    At least 6 classes
*    At least 2 uses of inheritance
*    At least 12 methods
*    At least one generic use
*    At least one static use -> displayBatteryModel()
*    Everything should be strongly typed
*/
var __extends = this.__extends || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    __.prototype = b.prototype;
    d.prototype = new __();
};
var DevicesOOP;
(function (DevicesOOP) {
    var BatteryModel = Enumerations.BatteryModel;

    (function (Enumerations) {
        (function (BatteryModel) {
            BatteryModel[BatteryModel["LiIon"] = 0] = "LiIon";
            BatteryModel[BatteryModel["NiMH"] = 1] = "NiMH";
            BatteryModel[BatteryModel["NiCd"] = 2] = "NiCd";
        })(Enumerations.BatteryModel || (Enumerations.BatteryModel = {}));
        var BatteryModel = Enumerations.BatteryModel;
    })(DevicesOOP.Enumerations || (DevicesOOP.Enumerations = {}));
    var Enumerations = DevicesOOP.Enumerations;

    (function (Software) {
        var Call = (function () {
            function Call(duration, phoneNumber, callTime) {
                this.duration = duration;
                this.phoneNumber = phoneNumber;
                this.callTime = callTime;
            }
            Object.defineProperty(Call.prototype, "duration", {
                get: function () {
                    return this._duration;
                },
                set: function (duration) {
                    if (duration <= 0) {
                        throw new Error('Call duration should be positive number');
                    }

                    this._duration = duration;
                },
                enumerable: true,
                configurable: true
            });


            Object.defineProperty(Call.prototype, "phoneNumber", {
                get: function () {
                    return this._phoneNumber;
                },
                set: function (phoneNumber) {
                    if (phoneNumber.length < 3) {
                        throw new Error('Phone number length should be longer than 3 digits');
                    }

                    this._phoneNumber = phoneNumber;
                },
                enumerable: true,
                configurable: true
            });


            Object.defineProperty(Call.prototype, "callTime", {
                get: function () {
                    return this._callTime;
                },
                set: function (callTime) {
                    this._callTime = callTime;
                },
                enumerable: true,
                configurable: true
            });


            Call.prototype.provideInfoAsString = function () {
                return 'Duration: ' + this.duration + 'seconds' + '\n' + 'Phone number: ' + this.phoneNumber + '\n' + 'Time of call: ' + this.callTime;
            };
            return Call;
        })();
        Software.Call = Call;
    })(DevicesOOP.Software || (DevicesOOP.Software = {}));
    var Software = DevicesOOP.Software;

    (function (Hardware) {
        var Battery = (function () {
            function Battery(model, serialNumber, capacity) {
                this.MAX_CAPACITY = 1360;
                this.model = model;
                this.serialNumber = serialNumber;
                this.capacity = capacity;
            }
            Object.defineProperty(Battery.prototype, "model", {
                get: function () {
                    return this._model;
                },
                set: function (model) {
                    this._model = model;
                },
                enumerable: true,
                configurable: true
            });


            Object.defineProperty(Battery.prototype, "serialNumber", {
                get: function () {
                    return this._serialNumber;
                },
                set: function (serialNumber) {
                    this._serialNumber = serialNumber;
                },
                enumerable: true,
                configurable: true
            });


            Object.defineProperty(Battery.prototype, "capacity", {
                get: function () {
                    return this._capacity;
                },
                set: function (capacity) {
                    this._capacity = capacity;
                },
                enumerable: true,
                configurable: true
            });


            Battery.prototype.provideInfoAsString = function () {
                return 'Model: ' + Battery.displayBatteryModel(this.model) + '\n' + 'Serial number: ' + this.serialNumber + '\n' + 'Hours talk: ' + this.capacity;
            };

            Battery.displayBatteryModel = function (batteryModel) {
                if (batteryModel === 0 /* LiIon */) {
                    return 'LiIon';
                } else if (batteryModel === 2 /* NiCd */) {
                    return 'NiCd';
                } else if (batteryModel === 1 /* NiMH */) {
                    return 'NiMH';
                } else {
                    throw new Error('It is possible to display only the available battery models');
                }
            };

            Battery.prototype.recharged = function () {
                this.capacity = this.MAX_CAPACITY;
            };
            return Battery;
        })();
        Hardware.Battery = Battery;

        var Device = (function () {
            function Device(price, serialNumber) {
                this.price = price;
                this.serialNumber = serialNumber;
            }
            Object.defineProperty(Device.prototype, "serialNumber", {
                get: function () {
                    return this._serialNumber;
                },
                set: function (serialNumber) {
                    this._serialNumber = serialNumber;
                },
                enumerable: true,
                configurable: true
            });


            Object.defineProperty(Device.prototype, "price", {
                get: function () {
                    return this._price;
                },
                set: function (price) {
                    this._price = price;
                },
                enumerable: true,
                configurable: true
            });


            Device.prototype.provideInfoAsString = function () {
                return 'Serial number: ' + this.serialNumber + '\n' + 'Price: ' + this.price;
            };
            return Device;
        })();
        Hardware.Device = Device;

        var MobileDevice = (function (_super) {
            __extends(MobileDevice, _super);
            function MobileDevice(price, serialNumber, batteryModel) {
                _super.call(this, price, serialNumber);

                this._batteryModel = batteryModel;
            }
            Object.defineProperty(MobileDevice.prototype, "batteryModel", {
                get: function () {
                    return this._batteryModel;
                },
                set: function (batteryModel) {
                    this._batteryModel = batteryModel;
                },
                enumerable: true,
                configurable: true
            });


            MobileDevice.prototype.provideInfoAsString = function () {
                return _super.prototype.provideInfoAsString.call(this) + '\n' + 'Battery model: ' + Battery.displayBatteryModel(this.batteryModel);
            };
            return MobileDevice;
        })(Device);
        Hardware.MobileDevice = MobileDevice;

        var AppleiPhone = (function (_super) {
            __extends(AppleiPhone, _super);
            function AppleiPhone(price, serialNumber, batteryModel) {
                _super.call(this, price, serialNumber, batteryModel);

                this._callHistory = [];
            }
            AppleiPhone.prototype.addCall = function (call) {
                this._callHistory.push(call);
            };

            AppleiPhone.prototype.removeLastCall = function () {
                var lastCall = this._callHistory[this._callHistory.length - 1];

                this._callHistory.pop();

                return lastCall;
            };
            AppleiPhone.prototype.clearCallHistory = function () {
                this._callHistory = [];
            };

            AppleiPhone.prototype.provideCallHistoryAsString = function () {
                var infoToProvide = '';

                for (var i = 0; i < this._callHistory.length - 1; i++) {
                    infoToProvide += 'Call: ' + (i + 1) + '\n' + this._callHistory[i].provideInfoAsString() + '\n';
                }

                infoToProvide += 'Call: ' + (this._callHistory.length - 1) + '\n' + this._callHistory[i].provideInfoAsString();

                return infoToProvide;
            };
            return AppleiPhone;
        })(MobileDevice);
        Hardware.AppleiPhone = AppleiPhone;
    })(DevicesOOP.Hardware || (DevicesOOP.Hardware = {}));
    var Hardware = DevicesOOP.Hardware;

    (function (GenericCollections) {
        var List = (function () {
            function List() {
            }
            List.prototype.add = function (item) {
                this._collection.push(item);
            };

            Object.defineProperty(List.prototype, "count", {
                get: function () {
                    return this._collection;
                },
                enumerable: true,
                configurable: true
            });
            return List;
        })();
        GenericCollections.List = List;
    })(DevicesOOP.GenericCollections || (DevicesOOP.GenericCollections = {}));
    var GenericCollections = DevicesOOP.GenericCollections;
})(DevicesOOP || (DevicesOOP = {}));
//# sourceMappingURL=classhierarchy.js.map
